package controllers

import (
	"database/sql"
	"github.com/360EntSecGroup-Skylar/excelize"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"math"
	"net/url"
	"nspel/entity"
	"nspel/model"
	"nspel/nspel"
	"nspel/util"
	"sort"
	"strconv"
	"time"
)

type SchoolsManageController struct {
	beego.Controller
}

func (c *SchoolsManageController) PostSchoolsImportCheck() {
	c.EnableRender = false
	requestData := new(model.PostStudentsImport)
	err := requestData.Validate(&c.Controller)
	if err != nil {
		c.Ctx.ResponseWriter.WriteHeader(400)
		nspel.HttpError(err, &c.Controller)
		return
	}
	excelData, err := util.TryParseXlsx(&requestData.ImportFile)
	if err != nil {
		c.Ctx.ResponseWriter.WriteHeader(400)
		nspel.HttpError(err, &c.Controller)
		return
	}
	msg, _, _, _, err := util.ValidateSchoolImport(&excelData)
	if err != nil {
		c.Ctx.ResponseWriter.WriteHeader(500)
		nspel.HttpError(err, &c.Controller)
		return
	}
	c.Data["json"] = msg
	c.ServeJSON()
}

func (c *SchoolsManageController) PostSchoolsImportSubmit() {
	c.EnableRender = false
	requestData := new(model.PostSchoolsImport)
	err := requestData.Validate(&c.Controller)
	if err != nil {
		c.Ctx.ResponseWriter.WriteHeader(400)
		nspel.HttpError(err, &c.Controller)
		return
	}
	excelData, err := util.TryParseXlsx(&requestData.ImportFile)
	if err != nil {
		c.Ctx.ResponseWriter.WriteHeader(400)
		nspel.HttpError(err, &c.Controller)
		return
	}
	msg, create, update, experimentAreaMap, err := util.ValidateSchoolImport(&excelData)
	if err != nil {
		c.Ctx.ResponseWriter.WriteHeader(500)
		nspel.HttpError(err, &c.Controller)
		return
	}
	if msg.Result {
		err = util.SchoolImport(&create, &update, &experimentAreaMap)
		if err != nil {
			c.Ctx.ResponseWriter.WriteHeader(500)
			nspel.HttpError(err, &c.Controller)
			return
		}
	}
	c.Data["json"] = msg
	c.ServeJSON()
}

func (c *SchoolsManageController) GetSchoolSelector() {
	defer c.ServeJSON()
	authority, ok := c.Ctx.Input.Session("authority").(byte)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	uid, ok := c.Ctx.Input.Session("uid").(int64)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	area := new(entity.Area)
	if authority == entity.ManagerAuthority.Administrator {
		areaId, err := c.GetInt64("area-id")
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
			return
		}
		area.Id = areaId
	} else if authority != entity.ManagerAuthority.Area {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "不支持请求"}
		return
	} else {
		err := area.SelectAllByUserId(uid)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
	}
	school := new(entity.School)
	schools, err := school.SelectAllByExperimentAreaId(area.Id)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	res := model.GetSchoolSelectorRes{RetCode: 0}
	res.School = make([]model.SchoolSelector, len(schools))
	for i := 0; i < len(schools); i++ {
		res.School[i].Id = schools[i].Id
		res.School[i].Value = schools[i].Name
	}
	c.Data["json"] = res
}

func (c *SchoolsManageController) GetSchoolList() {
	defer c.ServeJSON()
	authority, ok := c.Ctx.Input.Session("authority").(byte)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	uid, ok := c.Ctx.Input.Session("uid").(int64)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	if authority != entity.ManagerAuthority.Area && authority != entity.ManagerAuthority.Administrator {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "不支持请求"}
		return
	}
	res := model.GetSchoolsListRes{RetCode: 0}
	var count int64
	var schools []entity.School
	var err error
	if authority == entity.ManagerAuthority.Administrator {
		req := model.GetSchoolListAdministrator{}
		b := req.Validate("province-id", "city-id", "area-id", "school-name", "join-year", "page-size", "current-page", &c.Controller)
		if !b {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
			return
		}
		count, schools, err = util.GetSchoolsListAdministrator(req.ProvinceId, req.CityId, req.AreaId, req.SchoolName, req.JoinYear, req.PageSize, req.CurrentPage)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		res.Total = count
	} else if authority == entity.ManagerAuthority.Area {
		req := model.GetSchoolListArea{}
		b, err := req.Validate("join-year", "school-id", "page-size", "current-page", &c.Controller, uid)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		if !b {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
			return
		}
		area := new(entity.Area)
		err = area.SelectAllByUserId(uid)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		count, schools, err = util.GetSchoolsListArea(area.Id, req.JoinYear, req.SchoolId, req.PageSize, req.CurrentPage)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		res.Total = count
	} else {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "不支持请求"}
		return
	}
	res.Data = make([]model.SchoolsList, len(schools))
	for i := 0; i < len(res.Data); i++ {
		res.Data[i].Id = schools[i].Id
		province := new(entity.Province)
		err = province.SelectAllById(schools[i].ProvinceId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		city := new(entity.City)
		err = city.SelectAllById(schools[i].CityId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		area := new(entity.Area)
		err = area.SelectAllById(schools[i].AreaId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		experimentArea := new(entity.Area)
		err = experimentArea.SelectAllById(schools[i].ExperimentAreaId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		res.Data[i].ProvinceCityAreaName = province.Name + city.Name + area.Name
		res.Data[i].ExperimentAreaName = experimentArea.Name
		res.Data[i].Name = schools[i].Name
		if schools[i].SchoolType == 1 {
			res.Data[i].SchoolType = "小学"
		} else if schools[i].SchoolType == 4 {
			res.Data[i].SchoolType = "初中"
		} else if schools[i].SchoolType == 6 {
			res.Data[i].SchoolType = "高中"
		} else {
			res.Data[i].SchoolType = "未知"
		}
		res.Data[i].Headmaster = schools[i].HeadMaster.String
		res.Data[i].HeadmasterPhone = schools[i].HeadMasterPhone.String
		res.Data[i].HeadmasterEmail = schools[i].HeadMasterEmail.String
		res.Data[i].Contact = schools[i].Contact.String
		res.Data[i].ContactPhone = schools[i].ContactPhone.String
		res.Data[i].ContactEmail = schools[i].ContactEmail.String
		res.Data[i].IsStandout = util.GetBoolString(schools[i].IsStandout, "是", "否")
		res.Data[i].JoinAt = util.GetDateString(schools[i].JoinAt, "年", "月", "日", "")
		res.Data[i].StudentNum = schools[i].StudentNum
		res.Data[i].SchoolCode = schools[i].SchoolCode
		res.Data[i].Code = schools[i].Code.String
		res.Data[i].HasApply = util.GetBoolString(schools[i].HasApply, "是", "否")
		res.Data[i].Homepage = schools[i].Homepage.String
		res.Data[i].OfficialAccounts = schools[i].OfficialAccounts.String
		res.Data[i].IsExperiment = util.GetBoolString(schools[i].IsExperiment, "是", "否")
		res.Data[i].ExperimentAt = util.GetDateString(schools[i].ExperimentAt, "年", "月", "日", "")
		res.Data[i].StandoutAt = util.GetDateString(schools[i].StandoutAt, "年", "月", "日", "")
		res.Data[i].ContactAddress = schools[i].ContactAddress.String
	}
	c.Data["json"] = res
}

func (c *SchoolsManageController) PostSchoolCodeValidateExist() {
	defer c.ServeJSON()
	authority, ok := c.Ctx.Input.Session("authority").(byte)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	uid, ok := c.Ctx.Input.Session("uid").(int64)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	if authority != entity.ManagerAuthority.Administrator && authority != entity.ManagerAuthority.Area {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "不支持请求"}
		return
	}
	req := model.PostSchoolCodeValidateExist{}
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	b, err := req.Validate(uid, authority)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	if !b {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	school := new(entity.School)
	err = school.SelectAllBySchoolCode(req.SchoolCode)
	if err != nil {
		if err == orm.ErrNoRows {
			c.Data["json"] = map[string]interface{}{"retCode": 0, "result": true}
		} else {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
			return
		}
	} else {
		if school.Id == req.Id {
			c.Data["json"] = map[string]interface{}{"retCode": 0, "result": true}
			return
		} else {
			c.Data["json"] = map[string]interface{}{"retCode": 0, "result": false, "msg": "与其他学校编码重复"}
			return
		}
	}
}

func (c *SchoolsManageController) PostSchoolModify() {
	defer c.ServeJSON()
	authority, ok := c.Ctx.Input.Session("authority").(byte)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	uid, ok := c.Ctx.Input.Session("uid").(int64)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	req := model.PostSchoolModify{}
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	b, err := req.Validate(uid, authority)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	if !b {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	school := new(entity.School)
	err = school.SelectAllById(req.Id)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	school.Name = req.Name
	school.IsStandout = req.IsStandout
	if req.SchoolType == "小学" {
		school.SchoolType = entity.SchoolTypeMapName["小"].(byte)
	} else if req.SchoolType == "初中" {
		school.SchoolType = entity.SchoolTypeMapName["初"].(byte)
	} else if req.SchoolType == "高中" {
		school.SchoolType = entity.SchoolTypeMapName["高"].(byte)
	}
	school.HeadMaster = util.GetNullString(req.Headmaster)
	school.HeadMasterPhone = util.GetNullString(req.HeadmasterPhone)
	school.HeadMasterEmail = util.GetNullString(req.HeadmasterEmail)
	school.Contact = util.GetNullString(req.Contact)
	if len(req.ContactPhone) > 0 && !school.UserId.Valid {
		manager := new(entity.Manager)
		id, err := manager.Register(req.ContactPhone, req.ContactPhone, entity.ManagerAuthority.School)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		if school.UserId.Valid {
			err = manager.DeleteById(int64(school.UserId.Int64))
			if err != nil {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				return
			}
		}
		school.UserId = id
	} else if len(req.ContactPhone) > 0 {
		school.ContactPhone = util.GetNullString(req.ContactPhone)
	}
	school.ContactPhone = util.GetNullString(req.ContactPhone)
	school.ContactEmail = util.GetNullString(req.ContactEmail)
	school.JoinAt = req.JoinAt
	school.StudentNum = req.StudentNum
	school.SchoolCode = req.SchoolCode
	school.Code = util.GetNullString(req.Code)
	school.HasApply = req.HasApply
	school.Homepage = util.GetNullString(req.Homepage)
	school.OfficialAccounts = util.GetNullString(req.OfficialAccounts)
	school.IsExperiment = req.IsExperiment
	school.ExperimentAt = req.ExperimentAt
	school.StandoutAt = req.StandoutAt
	school.ContactAddress = util.GetNullString(req.ContactAddress)
	err = school.Update("name", "is_standout", "school_type", "headmaster", "headmaster_phone", "headmaster_email", "contact", "contact_phone", "contact_email", "join_at", "student_num", "school_code", "code", "has_apply", "homepage", "official_accounts", "is_experiment", "experiment_at", "standout_at", "contact_address", "user_id")
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	nspel.ResdisKeysDelete("manager", "school")
	err = util.UpdateAreaSchoolNum(school.ExperimentAreaId)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	c.Data["json"] = map[string]interface{}{"retCode": 0}
}

func (c *SchoolsManageController) PostSchoolAdd() {
	defer c.ServeJSON()
	authority, ok := c.Ctx.Input.Session("authority").(byte)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	uid, ok := c.Ctx.Input.Session("uid").(int64)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	req := model.PostSchoolAdd{}
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	b, err := req.Validate(uid, authority)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	if !b {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	school := new(entity.School)
	school.CountryId = req.CountryId
	school.ProvinceId = req.ProvinceId
	school.CityId = req.CityId
	school.AreaId = req.AreaId
	school.ExperimentAreaId = req.ExperimentAreaId
	school.Name = req.Name
	school.IsStandout = req.IsStandout
	if req.SchoolType == "小学" {
		school.SchoolType = entity.SchoolTypeMapName["小"].(byte)
	} else if req.SchoolType == "初中" {
		school.SchoolType = entity.SchoolTypeMapName["初"].(byte)
	} else if req.SchoolType == "高中" {
		school.SchoolType = entity.SchoolTypeMapName["高"].(byte)
	}
	school.HeadMaster = util.GetNullString(req.Headmaster)
	school.HeadMasterPhone = util.GetNullString(req.HeadmasterPhone)
	school.HeadMasterEmail = util.GetNullString(req.HeadmasterEmail)
	school.Contact = util.GetNullString(req.Contact)
	school.ContactPhone = util.GetNullString(req.ContactPhone)
	if school.ContactPhone.Valid {
		manager := new(entity.Manager)
		id, err := manager.Register(school.ContactPhone.String, school.ContactPhone.String, entity.ManagerAuthority.School)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		school.UserId = id
	}
	school.ContactEmail = util.GetNullString(req.ContactEmail)
	school.JoinAt = req.JoinAt
	school.StudentNum = req.StudentNum
	school.SchoolCode = req.SchoolCode
	school.Code = util.GetNullString(req.Code)
	school.HasApply = req.HasApply
	school.Homepage = util.GetNullString(req.Homepage)
	school.OfficialAccounts = util.GetNullString(req.OfficialAccounts)
	school.IsExperiment = req.IsExperiment
	school.ExperimentAt = req.ExperimentAt
	school.StandoutAt = req.StandoutAt
	school.ContactAddress = util.GetNullString(req.ContactAddress)
	err = school.Insert()
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	nspel.ResdisKeysDelete("school", "manager")
	err = util.UpdateAreaSchoolNum(school.ExperimentAreaId)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	c.Data["json"] = model.ErrorRes{RetCode: 0, Msg: "新建成功"}
}

func (c *SchoolsManageController) DeleteSchool() {
	defer c.ServeJSON()
	authority, ok := c.Ctx.Input.Session("authority").(byte)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	uid, ok := c.Ctx.Input.Session("uid").(int64)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	req := model.DeleteSchool{}
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	area := new(entity.Area)
	if authority == entity.ManagerAuthority.Area {
		err = area.SelectAllByUserId(uid)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
	}
	userId := make([]sql.NullInt64, len(req.Id))
	areaMap := make(map[int64]byte)
	for i := 0; i < len(req.Id); i++ {
		school := new(entity.School)
		err := school.SelectAllById(req.Id[i])
		userId[i] = school.UserId
		areaMap[school.ExperimentAreaId] = 0
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		student := new(entity.Student)
		num, err := student.SelectCountBySchoolId(req.Id[i])
		if num > 0 {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "无法删除有学生的学校"}
			return
		}
		if authority == entity.ManagerAuthority.Area {
			if school.ExperimentAreaId != area.Id {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
				return
			}
		}
	}
	for i := 0; i < len(req.Id); i++ {
		school := new(entity.School)
		err = school.DeleteById(req.Id[i])
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		if userId[i].Valid {
			manager := new(entity.Manager)
			err = manager.DeleteById(int64(userId[i].Int64))
			if err != nil {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				return
			}
		}
	}
	nspel.ResdisKeysDelete("school", "manager")
	for k := range areaMap {
		err = util.UpdateAreaSchoolNum(k)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
	}
	c.Data["json"] = map[string]interface{}{"retCode": 0, "msg": "删除成功"}
}

func (c *SchoolsManageController) GetSchoolType() {
	defer c.ServeJSON()
	authority, ok := c.Ctx.Input.Session("authority").(byte)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	uid, ok := c.Ctx.Input.Session("uid").(int64)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	schoolId, err := c.GetInt64("school-id")
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	school := new(entity.School)
	if authority == entity.ManagerAuthority.Area {
		area := new(entity.Area)
		err = area.SelectAllByUserId(uid)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		err = school.SelectAllById(schoolId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		if school.ExperimentAreaId != area.Id {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
			return
		}
	} else if authority == entity.ManagerAuthority.Administrator {
		err = school.SelectAllById(schoolId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
	} else if authority == entity.ManagerAuthority.School {
		err = school.SelectAllByUserId(uid)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
	}
	if entity.SchoolTypeMapCode[school.SchoolType] == "小" {
		c.Data["json"] = map[string]interface{}{"retCode": 0, "schoolType": "小学"}
	} else if entity.SchoolTypeMapCode[school.SchoolType] == "初" {
		c.Data["json"] = map[string]interface{}{"retCode": 0, "schoolType": "初中"}
	} else if entity.SchoolTypeMapCode[school.SchoolType] == "高" {
		c.Data["json"] = map[string]interface{}{"retCode": 0, "schoolType": "高中"}
	}
}

func (c *SchoolsManageController) GetSchoolOverview() {
	defer c.ServeJSON()
	authority, ok := c.Ctx.Input.Session("authority").(byte)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	uid, ok := c.Ctx.Input.Session("uid").(int64)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		return
	}
	var schoolId int64
	var schoolType byte
	if authority == entity.ManagerAuthority.Administrator {
		var err error
		schoolId, err = c.GetInt64("school-id")
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
			return
		}
		school := new(entity.School)
		err = school.SelectAllById(schoolId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		schoolType = school.SchoolType
	} else if authority == entity.ManagerAuthority.Area {
		var err error
		schoolId, err = c.GetInt64("school-id")
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
			return
		}
		area := new(entity.Area)
		err = area.SelectAllByUserId(uid)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		school := new(entity.School)
		err = school.SelectAllById(schoolId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		if area.Id != school.ExperimentAreaId {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
			return
		}
		schoolType = school.SchoolType
	} else if authority == entity.ManagerAuthority.School {
		school := new(entity.School)
		err := school.SelectAllByUserId(uid)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		schoolId = school.Id
		schoolType = school.SchoolType
	}
	score := new(entity.Score)
	lastYearDate := time.Now().AddDate(-1, 0, 0).Format("2006-01-02")
	ormEng := nspel.GetOrmEngine().QueryTable(score.TableName()).Filter("school_id", schoolId).Filter("measurement_date__gte", lastYearDate)
	scores, err := score.CustomSelectAll(&ormEng, "schoolId["+strconv.FormatInt(schoolId, 10)+"].measurementDate[>="+lastYearDate+"]")
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	res := model.GetSchoolOverviewRes{RetCode: 0}
	itemMap := make(map[string][2]float64)
	schoolMap := make(map[string][4]int64)
	for i := 0; i < len(scores); i++ {
		if scores[i].MissingTestNum == 0 {
			if scores[i].PhysicalTotalScore.Float64 >= 90 {
				res.Overall[0]++
				if scores[i].Sex == 1 {
					res.Boy[0]++
				} else {
					res.Girl[0]++
				}
				util.AddMapInt644(&schoolMap, util.GetGrades(scores[i].Grade), 0, 1)
			} else if scores[i].PhysicalTotalScore.Float64 >= 80 {
				res.Overall[1]++
				if scores[i].Sex == 1 {
					res.Boy[1]++
				} else {
					res.Girl[1]++
				}
				util.AddMapInt644(&schoolMap, util.GetGrades(scores[i].Grade), 1, 1)
			} else if scores[i].PhysicalTotalScore.Float64 >= 60 {
				res.Overall[2]++
				if scores[i].Sex == 1 {
					res.Boy[2]++
				} else {
					res.Girl[2]++
				}
				util.AddMapInt644(&schoolMap, util.GetGrades(scores[i].Grade), 2, 1)
			} else {
				res.Overall[3]++
				if scores[i].Sex == 1 {
					res.Boy[3]++
				} else {
					res.Girl[3]++
				}
				util.AddMapInt644(&schoolMap, util.GetGrades(scores[i].Grade), 3, 1)
			}
			util.AddMapFloat2(&itemMap, "总分", 0, scores[i].PhysicalTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "总分", 1, 1)
		}
		if scores[i].BodyMassIndex.Valid {
			util.AddMapFloat2(&itemMap, "BMI", 0, scores[i].BodyMassIndexTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "BMI", 1, 1)
		}
		if scores[i].VitalCapacity.Valid {
			util.AddMapFloat2(&itemMap, "肺活量", 0, scores[i].VitalCapacityTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "肺活量", 1, 1)
		}
		if scores[i].FiftyMeters.Valid {
			util.AddMapFloat2(&itemMap, "50米跑", 0, scores[i].FiftyMetersTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "50米跑", 1, 1)
		}
		if scores[i].SitAndReach.Valid {
			util.AddMapFloat2(&itemMap, "坐位体前屈", 0, scores[i].SitAndReachTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "坐位体前屈", 1, 1)
		}
		if scores[i].OneMinuteRopeSkipping.Valid {
			util.AddMapFloat2(&itemMap, "一分钟跳绳", 0, scores[i].OneMinuteRopeSkippingTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "一分钟跳绳", 1, 1)
		}
		if scores[i].OneMinuteSitUp.Valid {
			util.AddMapFloat2(&itemMap, "一分钟仰卧起坐", 0, scores[i].OneMinuteSitUpTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "一分钟仰卧起坐", 1, 1)
		}
		if scores[i].ShuttleRun.Valid {
			util.AddMapFloat2(&itemMap, "50米×8往返跑", 0, scores[i].ShuttleRunTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "50米×8往返跑", 1, 1)
		}
		if scores[i].StandingLongJump.Valid {
			util.AddMapFloat2(&itemMap, "立定跳远", 0, scores[i].StandingLongJumpTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "立定跳远", 1, 1)
		}
		if scores[i].Chinning.Valid {
			util.AddMapFloat2(&itemMap, "引体向上", 0, scores[i].ChinningTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "引体向上", 1, 1)
		}
		if scores[i].EightHundredMeters.Valid {
			util.AddMapFloat2(&itemMap, "耐力跑", 0, scores[i].EightHundredMetersTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "耐力跑", 1, 1)
		} else if scores[i].OneThousandMeters.Valid {
			util.AddMapFloat2(&itemMap, "耐力跑", 0, scores[i].OneThousandMetersTotalScore.Float64)
			util.AddMapFloat2(&itemMap, "耐力跑", 1, 1)
		}
	}
	var itemArray []string
	for k := range itemMap {
		if k != "总分" {
			itemArray = append(itemArray, k)
		}
	}
	sort.Strings(itemArray)
	itemArray = append([]string{"总分"}, itemArray...)
	res.Items = make([]map[string]interface{}, len(itemArray))
	for i := 0; i < len(itemArray); i++ {
		res.Items[i] = make(map[string]interface{})
		res.Items[i]["name"] = itemArray[i]
		if itemMap[itemArray[i]][1] == 0 {
			res.Items[i]["value"] = 0
		} else {
			res.Items[i]["value"] = float64(itemMap[itemArray[i]][0]) / float64(itemMap[itemArray[i]][1])
		}
	}
	var gradeItem []string
	for k := range schoolMap {
		gradeItem = append(gradeItem, k)
	}
	if entity.SchoolTypeMapCode[schoolType] == "小" {
		gradeItem = []string{"一年级", "二年级", "三年级", "四年级", "五年级", "六年级"}
	} else if entity.SchoolTypeMapCode[schoolType] == "初" {
		gradeItem = []string{"初一", "初二", "初三"}
	} else if entity.SchoolTypeMapCode[schoolType] == "高" {
		gradeItem = []string{"高一", "高二", "高三"}
	}
	res.Grade = make([]map[string]interface{}, len(gradeItem))
	for i := 0; i < len(gradeItem); i++ {
		res.Grade[i] = make(map[string]interface{})
		res.Grade[i]["name"] = gradeItem[i]
		res.Grade[i]["value"] = schoolMap[gradeItem[i]]
	}
	c.Data["json"] = res
}

func (c *SchoolsManageController) GetSchoolExport() {
	c.EnableRender = false
	authority, ok := c.Ctx.Input.Session("authority").(byte)
	if !ok {
		c.Ctx.ResponseWriter.Status = 403
		return
	}
	uid, ok := c.Ctx.Input.Session("uid").(int64)
	if !ok {
		c.Ctx.ResponseWriter.Status = 403
		return
	}
	if authority != entity.ManagerAuthority.Area && authority != entity.ManagerAuthority.Administrator {
		c.Ctx.ResponseWriter.Status = 400
		return
	}
	var schools []entity.School
	var err error
	if authority == entity.ManagerAuthority.Administrator {
		req := model.GetSchoolExportAdministratorReq{}
		b := req.Validate("province-id", "city-id", "area-id", "school-name", "join-year", &c.Controller)
		if !b {
			c.Ctx.ResponseWriter.Status = 400
			return
		}
		_, schools, err = util.GetSchoolsListAdministrator(req.ProvinceId, req.CityId, req.AreaId, req.SchoolName, req.JoinYear, math.MaxInt64, 1)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
	} else if authority == entity.ManagerAuthority.Area {
		req := model.GetSchoolExportAreaReq{}
		b, err := req.Validate("join-year", "school-id", &c.Controller, uid)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
		if !b {
			c.Ctx.ResponseWriter.Status = 400
			return
		}
		area := new(entity.Area)
		err = area.SelectAllByUserId(uid)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
		_, schools, err = util.GetSchoolsListArea(area.Id, req.JoinYear, req.SchoolId, math.MaxInt64, 1)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
	} else {
		c.Ctx.ResponseWriter.Status = 400
		return
	}
	widthMap := make(map[string]float64)
	xlsx := excelize.NewFile()
	xlsx.SetSheetName("Sheet1", "试验校")
	xlsx.SetCellValue("试验校", "A1", "序号")
	widthMap["A"] = math.Max(widthMap["A"], util.GetStrLength("序号")+1)
	xlsx.SetCellValue("试验校", "B1", "国籍")
	widthMap["B"] = math.Max(widthMap["B"], util.GetStrLength("国籍")+1)
	xlsx.SetCellValue("试验校", "C1", "省/直辖市")
	widthMap["C"] = math.Max(widthMap["C"], util.GetStrLength("省/直辖市")+1)
	xlsx.SetCellValue("试验校", "D1", "市/区")
	widthMap["D"] = math.Max(widthMap["D"], util.GetStrLength("市/区")+1)
	xlsx.SetCellValue("试验校", "E1", "区/县")
	widthMap["E"] = math.Max(widthMap["E"], util.GetStrLength("区/县")+1)
	xlsx.SetCellValue("试验校", "F1", "实验区")
	widthMap["F"] = math.Max(widthMap["F"], util.GetStrLength("实验区")+1)
	xlsx.SetCellValue("试验校", "G1", "学校名称")
	widthMap["G"] = math.Max(widthMap["G"], util.GetStrLength("学校名称")+1)
	xlsx.SetCellValue("试验校", "H1", "学校编码")
	widthMap["H"] = math.Max(widthMap["H"], util.GetStrLength("学校编码")+1)
	xlsx.SetCellValue("试验校", "I1", "编码")
	widthMap["I"] = math.Max(widthMap["I"], util.GetStrLength("学校编码")+1)
	xlsx.SetCellValue("试验校", "J1", "学生数量")
	widthMap["J"] = math.Max(widthMap["J"], util.GetStrLength("学生数量")+1)
	xlsx.SetCellValue("试验校", "K1", "学制")
	widthMap["K"] = math.Max(widthMap["K"], util.GetStrLength("学制")+1)
	xlsx.SetCellValue("试验校", "L1", "校长姓名")
	widthMap["L"] = math.Max(widthMap["L"], util.GetStrLength("校长姓名")+1)
	xlsx.SetCellValue("试验校", "M1", "校长电话")
	widthMap["M"] = math.Max(widthMap["M"], util.GetStrLength("校长电话")+1)
	xlsx.SetCellValue("试验校", "N1", "校长邮箱")
	widthMap["N"] = math.Max(widthMap["N"], util.GetStrLength("校长邮箱")+1)
	xlsx.SetCellValue("试验校", "O1", "联系人")
	widthMap["O"] = math.Max(widthMap["O"], util.GetStrLength("联系人")+1)
	xlsx.SetCellValue("试验校", "P1", "联系电话")
	widthMap["P"] = math.Max(widthMap["P"], util.GetStrLength("联系电话")+1)
	xlsx.SetCellValue("试验校", "Q1", "邮箱")
	widthMap["Q"] = math.Max(widthMap["Q"], util.GetStrLength("邮箱")+1)
	xlsx.SetCellValue("试验校", "R1", "申请表")
	widthMap["R"] = math.Max(widthMap["R"], util.GetStrLength("申请表")+1)
	xlsx.SetCellValue("试验校", "S1", "申请日期")
	widthMap["S"] = math.Max(widthMap["S"], util.GetStrLength("申请日期")+1)
	xlsx.SetCellValue("试验校", "T1", "学校网址")
	widthMap["T"] = math.Max(widthMap["T"], util.GetStrLength("学校网址")+1)
	xlsx.SetCellValue("试验校", "U1", "学校公众号")
	widthMap["U"] = math.Max(widthMap["U"], util.GetStrLength("学校公众号")+1)
	xlsx.SetCellValue("试验校", "V1", "是否授实验校牌匾")
	widthMap["V"] = math.Max(widthMap["V"], util.GetStrLength("是否授实验校牌匾")+1)
	xlsx.SetCellValue("试验校", "W1", "实验校颁牌时间")
	widthMap["W"] = math.Max(widthMap["W"], util.GetStrLength("实验校颁牌时间")+1)
	xlsx.SetCellValue("试验校", "X1", "是否示范校")
	widthMap["X"] = math.Max(widthMap["X"], util.GetStrLength("是否示范校")+1)
	xlsx.SetCellValue("试验校", "Y1", "示范校颁牌时间")
	widthMap["Y"] = math.Max(widthMap["Y"], util.GetStrLength("示范校颁牌时间")+1)
	xlsx.SetCellValue("试验校", "Z1", "联系地址")
	widthMap["Z"] = math.Max(widthMap["Z"], util.GetStrLength("联系地址")+1)
	for i := 0; i < len(schools); i++ {
		xlsx.SetCellValue("试验校", "A"+strconv.Itoa(i+2), i+1)
		widthMap["A"] = math.Max(widthMap["A"], util.GetStrLength(strconv.Itoa(i+1))+1)
		country := new(entity.Country)
		err = country.SelectAllById(schools[i].CountryId)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
		xlsx.SetCellValue("试验校", "B"+strconv.Itoa(i+2), country.Name)
		widthMap["B"] = math.Max(widthMap["B"], util.GetStrLength(country.Name)+1)
		province := new(entity.Province)
		err = province.SelectAllById(schools[i].ProvinceId)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
		xlsx.SetCellValue("试验校", "C"+strconv.Itoa(i+2), province.Name)
		widthMap["C"] = math.Max(widthMap["C"], util.GetStrLength(province.Name)+1)
		city := new(entity.City)
		err = city.SelectAllById(schools[i].CityId)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
		xlsx.SetCellValue("试验校", "D"+strconv.Itoa(i+2), city.Name)
		widthMap["D"] = math.Max(widthMap["D"], util.GetStrLength(city.Name)+1)
		area := new(entity.Area)
		err = area.SelectAllById(schools[i].AreaId)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
		xlsx.SetCellValue("试验校", "E"+strconv.Itoa(i+2), area.Name)
		widthMap["E"] = math.Max(widthMap["E"], util.GetStrLength(area.Name)+1)
		err = area.SelectAllById(schools[i].ExperimentAreaId)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
		xlsx.SetCellValue("试验校", "F"+strconv.Itoa(i+2), area.Name)
		widthMap["F"] = math.Max(widthMap["F"], util.GetStrLength(area.Name)+1)
		xlsx.SetCellValue("试验校", "G"+strconv.Itoa(i+2), schools[i].Name)
		widthMap["G"] = math.Max(widthMap["G"], util.GetStrLength(schools[i].Name)+1)
		xlsx.SetCellValue("试验校", "H"+strconv.Itoa(i+2), schools[i].SchoolCode)
		widthMap["H"] = math.Max(widthMap["H"], util.GetStrLength(schools[i].SchoolCode)+1)
		xlsx.SetCellValue("试验校", "I"+strconv.Itoa(i+2), schools[i].Code.String)
		widthMap["I"] = math.Max(widthMap["I"], util.GetStrLength(schools[i].Code.String)+1)
		xlsx.SetCellValue("试验校", "J"+strconv.Itoa(i+2), schools[i].StudentNum)
		widthMap["J"] = math.Max(widthMap["J"], util.GetStrLength(strconv.FormatInt(schools[i].StudentNum, 10))+1)
		xlsx.SetCellValue("试验校", "K"+strconv.Itoa(i+2), entity.SchoolTypeMapCode[schools[i].SchoolType])
		widthMap["K"] = math.Max(widthMap["K"], util.GetStrLength(entity.SchoolTypeMapCode[schools[i].SchoolType])+1)
		xlsx.SetCellValue("试验校", "L"+strconv.Itoa(i+2), schools[i].HeadMaster.String)
		widthMap["L"] = math.Max(widthMap["L"], util.GetStrLength(schools[i].HeadMaster.String)+1)
		xlsx.SetCellValue("试验校", "M"+strconv.Itoa(i+2), schools[i].HeadMasterPhone.String)
		widthMap["M"] = math.Max(widthMap["M"], util.GetStrLength(schools[i].HeadMasterPhone.String)+1)
		xlsx.SetCellValue("试验校", "N"+strconv.Itoa(i+2), schools[i].HeadMasterEmail.String)
		widthMap["N"] = math.Max(widthMap["N"], util.GetStrLength(schools[i].HeadMasterEmail.String)+1)
		xlsx.SetCellValue("试验校", "O"+strconv.Itoa(i+2), schools[i].Contact.String)
		widthMap["O"] = math.Max(widthMap["O"], util.GetStrLength(schools[i].Contact.String)+1)
		xlsx.SetCellValue("试验校", "P"+strconv.Itoa(i+2), schools[i].ContactPhone.String)
		widthMap["P"] = math.Max(widthMap["P"], util.GetStrLength(schools[i].ContactPhone.String)+1)
		xlsx.SetCellValue("试验校", "Q"+strconv.Itoa(i+2), schools[i].ContactEmail.String)
		widthMap["Q"] = math.Max(widthMap["Q"], util.GetStrLength(schools[i].ContactEmail.String)+1)
		xlsx.SetCellValue("试验校", "R"+strconv.Itoa(i+2), util.GetBoolString(schools[i].HasApply, "有", "无"))
		widthMap["R"] = math.Max(widthMap["R"], util.GetStrLength("有")+1)
		if !schools[i].JoinAt.IsZero() {
			xlsx.SetCellValue("试验校", "S"+strconv.Itoa(i+2), schools[i].JoinAt.Format("2006/01/02"))
			widthMap["S"] = math.Max(widthMap["S"], util.GetStrLength(schools[i].JoinAt.Format("2006/01/02"))+1)
		}
		xlsx.SetCellValue("试验校", "T"+strconv.Itoa(i+2), schools[i].Homepage.String)
		widthMap["T"] = math.Max(widthMap["T"], util.GetStrLength(schools[i].Homepage.String)+1)
		xlsx.SetCellValue("试验校", "U"+strconv.Itoa(i+2), schools[i].OfficialAccounts.String)
		widthMap["U"] = math.Max(widthMap["U"], util.GetStrLength(schools[i].OfficialAccounts.String)+1)
		xlsx.SetCellValue("试验校", "V"+strconv.Itoa(i+2), util.GetBoolString(schools[i].IsExperiment, "是", "否"))
		widthMap["V"] = math.Max(widthMap["V"], util.GetStrLength("有")+1)
		if !schools[i].ExperimentAt.IsZero() {
			xlsx.SetCellValue("试验校", "W"+strconv.Itoa(i+2), schools[i].ExperimentAt.Format("2006/01/02"))
			widthMap["W"] = math.Max(widthMap["W"], util.GetStrLength(schools[i].ExperimentAt.Format("2006/01/02"))+1)
		}
		xlsx.SetCellValue("试验校", "X"+strconv.Itoa(i+2), util.GetBoolString(schools[i].IsStandout, "是", "否"))
		widthMap["X"] = math.Max(widthMap["X"], util.GetStrLength("是")+1)
		if !schools[i].StandoutAt.IsZero() {
			xlsx.SetCellValue("试验校", "Y"+strconv.Itoa(i+2), schools[i].StandoutAt.Format("2006/01/02"))
			widthMap["Y"] = math.Max(widthMap["Y"], util.GetStrLength(schools[i].StandoutAt.Format("2006/01/02"))+1)
		}
		xlsx.SetCellValue("试验校", "Z"+strconv.Itoa(i+2), schools[i].ContactAddress.String)
		widthMap["Z"] = math.Max(widthMap["Z"], util.GetStrLength(schools[i].ContactAddress.String)+1)
	}
	for k, v := range widthMap {
		xlsx.SetColWidth("试验校", k, k, v)
	}
	buffer, err := xlsx.WriteToBuffer()
	if err != nil {
		c.Ctx.ResponseWriter.Status = 500
		nspel.Error(err)
		return
	}
	c.Ctx.Output.Header("Content-Disposition", "attachment; filename="+url.PathEscape("试验校.xlsx"))
	c.Ctx.Output.Header("Content-Description", "File Transfer")
	c.Ctx.Output.Header("Content-Type", "application/octet-stream")
	c.Ctx.Output.Header("Content-Transfer-Encoding", "binary")
	c.Ctx.Output.Header("Expires", "0")
	c.Ctx.Output.Header("Cache-Control", "must-revalidate")
	c.Ctx.Output.Header("Pragma", "public")
	c.Ctx.ResponseWriter.Write(buffer.Bytes())
}
